package com.ruoyi.system.service.impl;

import java.math.BigDecimal;
import java.util.List;
import java.util.regex.Pattern;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.system.mapper.MdMaterialMapper;
import com.ruoyi.system.domain.MdMaterial;
import com.ruoyi.system.service.IMdMaterialService;

/**
 * 物料主数据Service业务层处理
 * 
 * @author ruoyi
 * @date 2025-06-22
 */
@Service
public class MdMaterialServiceImpl implements IMdMaterialService 
{
    @Autowired
    private MdMaterialMapper mdMaterialMapper;

    /**
     * 查询物料主数据
     * 
     * @param id 物料主数据主键
     * @return 物料主数据
     */
    @Override
    public MdMaterial selectMdMaterialById(String id)
    {
        return mdMaterialMapper.selectMdMaterialById(id);
    }

    /**
     * 查询物料主数据列表
     * 
     * @param mdMaterial 物料主数据
     * @return 物料主数据
     */
    @Override
    public List<MdMaterial> selectMdMaterialList(MdMaterial mdMaterial)
    {
        return mdMaterialMapper.selectMdMaterialList(mdMaterial);
    }

    /**
     * 新增物料主数据
     * 
     * @param mdMaterial 物料主数据
     * @return 结果
     */
    @Override
    public int insertMdMaterial(MdMaterial mdMaterial)
    {
        // 生成主键ID
        mdMaterial.setId(IdUtils.simpleUUID());
        // 设置创建时间
        mdMaterial.setCreateTime(DateUtils.getNowDate());
        // 设置删除标志
        mdMaterial.setDelFlag("0");
        // 设置默认库存量
        if (mdMaterial.getInStock() == null) {
            mdMaterial.setInStock(BigDecimal.ZERO);
        }
        return mdMaterialMapper.insertMdMaterial(mdMaterial);
    }

    /**
     * 修改物料主数据
     * 
     * @param mdMaterial 物料主数据
     * @return 结果
     */
    @Override
    public int updateMdMaterial(MdMaterial mdMaterial)
    {
        mdMaterial.setUpdateTime(DateUtils.getNowDate());
        return mdMaterialMapper.updateMdMaterial(mdMaterial);
    }

    /**
     * 批量删除物料主数据
     * 
     * @param ids 需要删除的物料主数据主键
     * @return 结果
     */
    @Override
    public int deleteMdMaterialByIds(String[] ids)
    {
        return mdMaterialMapper.deleteMdMaterialByIds(ids);
    }

    /**
     * 删除物料主数据信息
     * 
     * @param id 物料主数据主键
     * @return 结果
     */
    @Override
    public int deleteMdMaterialById(String id)
    {
        return mdMaterialMapper.deleteMdMaterialById(id);
    }

    /**
     * 检查物料号在工厂内是否唯一
     * 
     * @param plantCode 工厂代码
     * @param materialCode 物料号
     * @param id 物料ID（编辑时排除自身）
     * @return 结果
     */
    @Override
    public boolean checkMaterialCodeUnique(String plantCode, String materialCode, String id)
    {
        int count = mdMaterialMapper.checkMaterialCodeUnique(plantCode, materialCode, id);
        return count == 0;
    }

    /**
     * 导入物料数据
     * 
     * @param materialList 物料数据列表
     * @param isUpdateSupport 是否更新支持，如果已存在，则进行更新数据
     * @param operName 操作用户
     * @return 结果
     */
    @Override
    public String importMaterial(List<MdMaterial> materialList, Boolean isUpdateSupport, String operName)
    {
        if (StringUtils.isNull(materialList) || materialList.size() == 0)
        {
            throw new RuntimeException("导入物料数据不能为空！");
        }
        int successNum = 0;
        int failureNum = 0;
        int updateNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        
        for (MdMaterial material : materialList)
        {
            try
            {
                // 验证必填字段
                if (StringUtils.isEmpty(material.getPlantCode()))
                {
                    failureNum++;
                    failureMsg.append("<br/>工厂代码不能为空");
                    continue;
                }
                if (StringUtils.isEmpty(material.getMaterialCode()))
                {
                    failureNum++;
                    failureMsg.append("<br/>物料号不能为空");
                    continue;
                }
                if (StringUtils.isEmpty(material.getMaterialDesc()))
                {
                    failureNum++;
                    failureMsg.append("<br/>物料描述不能为空");
                    continue;
                }
                if (StringUtils.isEmpty(material.getMaterialType()))
                {
                    failureNum++;
                    failureMsg.append("<br/>物料类型不能为空");
                    continue;
                }

                // 验证物料号格式
                if (!isValidMaterialCode(material.getMaterialCode()))
                {
                    failureNum++;
                    failureMsg.append("<br/>物料号格式错误，必须以字母开头，长度6-20字符，只能包含字母数字和'-'");
                    continue;
                }

                // 验证物料类型
                if (!isValidMaterialType(material.getMaterialType()))
                {
                    failureNum++;
                    failureMsg.append("<br/>物料类型无效，只能是MAKE、OUTSOURCE、PURCHASE");
                    continue;
                }

                // 查询是否存在
                MdMaterial existMaterial = mdMaterialMapper.selectMdMaterialByCode(
                    material.getPlantCode(), material.getMaterialCode());

                if (StringUtils.isNull(existMaterial))
                {
                    // 新增
                    material.setId(IdUtils.simpleUUID());
                    material.setCreateBy(operName);
                    material.setCreateTime(DateUtils.getNowDate());
                    material.setDelFlag("0");
                    if (material.getInStock() == null) {
                        material.setInStock(BigDecimal.ZERO);
                    }
                    this.insertMdMaterial(material);
                    successNum++;
                    successMsg.append("<br/>").append(successNum).append("、物料号 ").append(material.getMaterialCode()).append(" 导入成功");
                }
                else if (isUpdateSupport)
                {
                    // 更新
                    existMaterial.setMaterialDesc(material.getMaterialDesc());
                    existMaterial.setMaterialType(material.getMaterialType());
                    if (material.getInStock() != null) {
                        existMaterial.setInStock(material.getInStock());
                    }
                    if (StringUtils.isNotEmpty(material.getRemark())) {
                        existMaterial.setRemark(material.getRemark());
                    }
                    existMaterial.setUpdateBy(operName);
                    existMaterial.setUpdateTime(DateUtils.getNowDate());
                    this.updateMdMaterial(existMaterial);
                    updateNum++;
                    successMsg.append("<br/>").append(updateNum).append("、物料号 ").append(material.getMaterialCode()).append(" 更新成功");
                }
                else
                {
                    failureNum++;
                    failureMsg.append("<br/>物料号 ").append(material.getMaterialCode()).append(" 已存在");
                }
            }
            catch (Exception e)
            {
                failureNum++;
                String msg = "<br/>物料号 " + material.getMaterialCode() + " 导入失败：";
                failureMsg.append(msg).append(e.getMessage());
            }
        }
        
        if (failureNum > 0)
        {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new RuntimeException(failureMsg.toString());
        }
        else
        {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + (successNum + updateNum) + " 条，数据如下：");
        }
        return successMsg.toString();
    }

    /**
     * 验证物料号格式
     * 
     * @param materialCode 物料号
     * @return 验证结果
     */
    private boolean isValidMaterialCode(String materialCode)
    {
        if (StringUtils.isEmpty(materialCode))
        {
            return false;
        }
        // 必须以字母开头，长度6-20字符，只能包含字母数字和'-'
        String pattern = "^[A-Za-z][A-Za-z0-9\\-]{5,19}$";
        return Pattern.matches(pattern, materialCode);
    }

    /**
     * 验证物料类型
     * 
     * @param materialType 物料类型
     * @return 验证结果
     */
    private boolean isValidMaterialType(String materialType)
    {
        return "MAKE".equals(materialType) || "OUTSOURCE".equals(materialType) || "PURCHASE".equals(materialType);
    }
} 